#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

// qsort函数 利用（快速排序）算法 实现任意类型的数据排序，可利用性高
void qsort(
	void* base,		// 比较数据的起始地址
	size_t num,		// 待排序的数据元素个数
	size_t width,	// 待排序的数据的大小（字节）
	int(*compare)(const void* elem1, const void* elem2)		// 比较函数
);

void Bsort(void* base, size_t num, size_t width, int(_cdecl *pf)(const void* e1, const void* e2));

// __cdecl 函数调用约定

//void bubble_sort(int* arr, int len)       // 只能对整形的数据进行排序，局限性太大
//{
//	
//	for (int i = 0; i < len - 1; i++)
//	{
//		int flag = 1;
//		for (int j = 0; j < len - 1 - i; j++)
//		{
//			if (arr[j] > arr[j + 1])
//			{
//				flag = 0;
//				int temp = arr[j];
//				arr[j] = arr[j + 1];
//				arr[j + 1] = temp;
//			}
//		}
//		if (flag)
//			break;
//	}
//}

void swap(char* e1, char* e2,size_t  width)   // 交换字节
{
	while (width--)
	{
		char temp = *e1;
		*e1 = *e2;
		*e2 = temp;
		e1++, e2++;
	}
}

// void * 类型的指针，无具体类型的指针，指向的空间不确定类型，可以存放任意类型的地址，但是不能解引用和+ - 操作
// Bsort 利用（冒泡排序算法） 实现任意类型数据的排序
void Bsort(void* base, size_t num, size_t width, int(*pf)(const void* e1, const void* e2))
{
	size_t  i, j;
	char* base_p = (char*)base;
	for (i = 0; i < num - 1; i++)
	{
		int flag = 1;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (pf(base_p + width * j, base_p + width * (j + 1) ))
			{
				flag = 0;
				// 交换函数
				swap(base_p + width * j, base_p + width * (j + 1) ,width);
			}
		}
		if (flag)
			break;
	}
}

int cmp_int(const void* elem1, const void* elem2)
{
	int* p1 = (int*)elem1;
	int* p2 = (int*)elem2;
	return *p2 - *p1;
}
int cmp_char(const void* elem1, const void* elem2)
{
	char* p1 = (char*)elem1;
	char* p2 = (char*)elem2;
	return *p2 - *p1;   // 后一个比前一个大 返回 1
}

struct student
{
	char* name;
	int age;
};

cmp_struct(const void* elem1, const void* elem2)
{
	struct student* p1 = (struct student*)elem1;
	struct student* p2 = (struct student*)elem2;
	return p2->age - p1->age;
}


int main()
{
	// int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
	// int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	// char arr[10] = { 'a','b','c','d','e','f','g' };
	struct student arr[3] = {
		{"小红",15},
		{"小绿",17},
		{"小蓝",18},
	};
	int sz = sizeof(arr) / sizeof(arr[0]);
	
	// bubble_sort(arr, sz);
	Bsort(arr, 3 ,sizeof arr[0], cmp_struct);   // 函数名就是函数的地址，     函数名 <=>  &函数名

	for (int i = 0; i < sz; i++)
	{
		printf("%s ", arr[i].name);
	}
	
	return 0;
}